// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ImportExportAdapterTest.cs" company="">
//   
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Tests
{
    using System;
    using System.Threading;

    using ExecutionTool.Common;
    using ExecutionTool.ImportExport;
    using ExecutionTool.Profile;

    using Microsoft.Practices.EnterpriseLibrary.Logging;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    using Moq;

    using Timer = System.Timers.Timer;

    [TestClass]
    public class ImportExportAdapterTest
    {
        #region Constants

        private const string Endpoint = "https://sn1prod-dacsvc.azure.com/DACWebService.svc";

        private const string FailureRequestId = "3c05a63a-6da9-461f-bef2-e5b99408e0d6";

        private const string SuccessfulRequestId = "b3d0ff0b-5490-4d09-8d0a-6972e79343c2";

        #endregion

        #region Fields

        private Mock<LogWriter> loggerMock;

        private SqlAzureLocation source;

        private AzureStorageLocation target;

        #endregion

        #region Public Methods and Operators

        [TestMethod]
        [ExpectedException(typeof(StepFaultException))]
        public void CheckStatusFailure()
        {
            var adapter = new ImportExportServiceAdatper(this.loggerMock.Object);
            adapter.GetOperationProgress(Endpoint, this.source, Guid.Parse(FailureRequestId), StepType.Export);
        }

        [TestMethod]
        public void CheckStatusSuccess()
        {
            var adapter = new ImportExportServiceAdatper(this.loggerMock.Object);
            var progress = adapter.GetOperationProgress(Endpoint, this.source, Guid.Parse(SuccessfulRequestId), StepType.Export);
            Assert.AreEqual(100, progress);
        }

        [TestMethod]
        [Ignore]
        public void IntegrationTest()
        {
            var storageAdapter = new StorageAdapter(this.loggerMock.Object);
            storageAdapter.CreateContainerIfNotExistAsync(this.target, "unittest").Wait();

            // start an export
            var adapter = new ImportExportServiceAdatper(this.loggerMock.Object);
            string blobUri = string.Format("https://{0}.blob.core.windows.net/{1}", this.target.StorageAccount, "unittest/UnitTest.bacpac");
            var id = TryCatchHelper(() => adapter.TriggerExport(Endpoint, this.source, this.target, blobUri, this.source.DatabaseName));

            // monitoring progress
            var wait = new ManualResetEvent(false);
            var timer = new Timer(5000);
            timer.Elapsed += (o, e) =>
                {
                    try
                    {
                        var newProgress = adapter.GetOperationProgress(Endpoint, this.source, id, StepType.Export);
                        Console.WriteLine("{0}: {1}%", DateTime.UtcNow, newProgress);

                        if (newProgress < 100)
                        {
                            return;
                        }

                        wait.Set();
                        timer.Dispose();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                    }
                };

            timer.Enabled = true;
            wait.WaitOne();

            // cleanup
            TryCatchHelper(() => StorageHelper.DeleteBlob(this.target.StorageAccount, this.target.AccessKey, blobUri));
        }

        [TestInitialize]
        public void Setup()
        {
            this.source = new SqlAzureLocation { ServerNamePrefix = "yj63a5jos3", UserName = "devscus", Password = "P@ssw)rd", DatabaseName = "POC" };

            this.target = new AzureStorageLocation
                {
                    StorageAccount = "dataprotectorpoc", 
                    AccessKey = "Oz8JVCBWmDvJBoIIiKVCLtzapCeHo7ZaV5Edvfq7Jl7NeUGjkCyUGV4gKmjLB6/Wq6dpDMdKtRbdj31mKIx7DQ==", 
                };

            this.loggerMock = new Mock<LogWriter>();
        }

        [TestMethod]
        public void TestSplit()
        {
            string status = "Running, Progress = 47.5%";

            var array = status.Split('=');
            foreach (var item in array)
            {
                Console.WriteLine("[{0}]", item);
            }

            var progress = array[1].Trim(' ', '%');
            Console.WriteLine(progress);
        }

        #endregion

        #region Methods

        private static T TryCatchHelper<T>(Func<T> func)
        {
            try
            {
                return func();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                throw;
            }
        }

        private static void TryCatchHelper(Action action)
        {
            try
            {
                action();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                Assert.Fail();
            }
        }

        #endregion
    }
}
